package org.jprobe.junit;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;

import org.jprobe.JProbeException;
import org.jprobe.codegen.BeanGetterValueInterface;

/**
 * Specifications of Junit 4 Test case generator
 * @author Hussain Al-Mutawa
 * @version 1.0
 */
public interface JUnitTestCaseGeneratorInterface {
	/**
	 * generates all of the test cases for the given class
	 * after running the bean inspector
	 * @throws Exception if the bean inspection fails due to inability to generate code/compile/or fetch result
	 * @return the same JUnitTestCaseGeneratorInterface object after finishing test cases generation
	 **/
	JUnitTestCaseGeneratorInterface generate() throws JProbeException, Exception;
	/**
	 * gets an assertion statement as string, if the method is mutator
	 * @param method -the method used to get the result from which
	 * must return non (Void) value to be tested
	 * @param actual -the actual value returned by the BeanInspector
	 * @return a string of an assertion statement
	 * @throws Exception if code generation fails
	 */
	String getAssertion(Method method,BeanGetterValueInterface actual) throws Exception;
	/**
	 * gets list of constructors test unit blocks
	 * @return array of assertion codes (constructors)
	 */
	JUnitTestUnitBlockInterface<Constructor<?>>[]getConstructorsJUnitTestUnitBlocks();
	/**
	 * gets the list of all test unit blocks generated by
	 * the class which to be tested
	 * @return array of assertion codes
	 */
	JUnitTestUnitBlockInterface<? extends Member>[]getJUnitTestUnitBlocks();
	/**
	 * gets list of methods test unit blocks
	 * @return array of assertion codes (methods)
	 */
	JUnitTestUnitBlockInterface<Method>[]getMethodsJUnitTestUnitBlocks();
	/**
	 * gets list of private methods test unit blocks (using reflection)
	 * @return array of assertion codes (methods)
	 */
	JUnitTestUnitBlockInterface<Method>[]getPrivateMethodsJUnitTestUnitBlocks();
	/**
	 * gets the class used to generate test cases
	 */
	Class<?>getTargetClass();
	/**
	 * gets the class <a href='http://docs.oracle.com/javase/6/docs/api/java/lang/ClassLoader.html#name'>binary name</a>
	 * of the generated test unit cases class
	 * @return test unit class name
	 */
	String getTestUnitClassName();
	/**
	 * resets each collection in this unit test generator
	 */
	void resetCollections();
	/**
	 * gets the target class for which unit test cases are generated
	 * @param targetClass the class that for which unit tests are generated
	 */
	void setTargetClass(Class<?>targetClass);
	/**
	 * gets a string of junit assertion for all of the getters one after another
	 * @param bean the bean to be tested
	 * @param obj an initialized instance of the bean
	 * @return string of junit assertions java code
	 * @throws Exception if code generation has failed
	 */
	String getAllGettersAssertions(Class<?> bean, Object obj) throws Exception;
	/**
	 * gets the generated test case file name
	 * @return the full path to the generated test case file name
	 */
	String getTestFileName();
	/**
	 * generates the test case for the current class
	 * @throws IOException if writing to the target project fails
	 */
	void generateTestCase() throws IOException;
}
